package config

import (
	"fmt"
	"github.com/BurntSushi/toml"
	"github.com/sirupsen/logrus"
	"strings"
	"time"
)

type Cfg struct {
	Server   Server   `json:"Server" toml:"Server" yaml:"Server"`
	Database Database `json:"Database" toml:"Database" yaml:"Database"`
}

type Server struct {
	RunMode      string        `json:"RunMode" toml:"RunMode" yaml:"RunMode"`
	Port         int           `json:"Port" toml:"Port" yaml:"Port"`
	ReadTimeout  time.Duration `json:"ReadTimeout" toml:"ReadTimeout" yaml:"ReadTimeout"`
	WriteTimeout time.Duration `json:"WriteTimeout" toml:"WriteTimeout" yaml:"WriteTimeout"`
}

type Database struct {
	Type        string `json:"Type" toml:"Type" yaml:"Type"`
	User        string `json:"User" toml:"User" yaml:"User"`
	Password    string `json:"Password" toml:"Password" yaml:"Password"`
	Host        string `json:"Host" toml:"Host" yaml:"Host"`
	Name        string `json:"Name" toml:"Name" yaml:"Name"`
	TablePrefix string `json:"TablePrefix" toml:"TablePrefix" yaml:"TablePrefix"`
}

type ErrConfigValidationFailed struct {
	confFile       string
	UndecodedItems []string
}

func (e *ErrConfigValidationFailed) Error() string {
	return fmt.Sprintf("config file %s contained invalid configuration options: %s; check ", e.confFile, strings.Join(
		e.UndecodedItems, ", "))

}

var Global = &Cfg{}

func Setup() {
	var err error
	err = Global.Load("config/config.toml")
	if err != nil {
		logrus.Fatalf("read config/config.toml is err: %v", err)
	}
	// 将时间转成指定的超时时间
	Global.TimeFormat()
}

func (c *Cfg) Load(confFile string) error {
	metaData, err := toml.DecodeFile(confFile, c)
	// If any items in confFile file are not mapped into the Config struct, issue
	// an error and stop the server from starting.
	unencoded := metaData.Undecoded()
	if len(unencoded) > 0 && err == nil {
		var unencodedItems []string
		for _, item := range unencoded {
			unencodedItems = append(unencodedItems, item.String())
		}
		err = &ErrConfigValidationFailed{confFile, unencodedItems}
	}

	return err
}

func (c *Cfg) TimeFormat() {
	c.Server.ReadTimeout = c.Server.ReadTimeout * time.Second
	c.Server.WriteTimeout = c.Server.WriteTimeout * time.Second
}
